<template>
	<view class="container">
		<!-- 顶部导航栏 -->
		<view class="nav-bar">
			<image class="nav-icon" src="../../static/history.png" mode="widthFix" @tap="toggle('left')"></image>
			<text class="nav-title">新对话</text>
			<image class="nav-icon" src="../../static/new.png" mode="widthFix" @tap='newChat'></image>
		</view>


		<!-- 显示对话记录列表 -->
		<view class="message-container" v-if='chatlists.length > 0'>
			<!-- 占位符 -->
			<view class="nav-bar-empty"> </view>
			<template v-for="(chat, ind) in chatlists">
				<!-- 用户消息 -->
				<view class="message-item reply-message" v-if="chat.role == 'user'">
					<view class="message-content">
						<text class="message-text">{{chat.content}}</text>
					</view>
				</view>
				<!-- 回复消息 -->
				<view class="message-item user-message" v-if="chat.role == 'assistant'">
					<image class="avatar" src="/static/dt.png" mode="aspectFill"></image>
					<view class="message-content wbg">
						<zero-markdown-view :markdown="chat.content" :aiMode='true'></zero-markdown-view>
						<!-- <text class="message-text">{{chat.content}}</text> -->
					</view>
				</view>
			</template>
			<!-- 临时显示：开始 -->
			<view class="message-item user-message" v-if="streamcontent">
				<image class="avatar" src="/static/dt.png" mode="aspectFill"></image>
				<view class="message-content wbg">
					<zero-markdown-view :markdown="streamcontent" :aiMode='true'></zero-markdown-view>
				</view>
			</view>
			<!-- 临时显示：结束 -->

			<!-- 占位符 -->
			<view class="tmp-bottom"> </view>

		</view>

		<!-- 中间 Logo 和提示语 -->
		<view class="main-content" v-else>
			<image class="logo" src="../../static/ds.png" mode="widthFix"></image>
			<text class="welcome">嗨！我是 DeepSeek</text>
			<text class="desc">
				我可以帮你搜索、答疑、写作，请把你的任务交给我吧~
			</text>
		</view>

		<!-- 底部输入框 -->
		<view class="input-area">
			<textarea auto-height class="msg-input" v-model="msg" placeholder="给 DeepSeek 发送消息"
				placeholder-class="input-placeholder" />
			<view class="input-options">
				<view class="option" @tap="deepThing" :style="{backgroundColor: dt_bgc}">
					<image class="option-icon" src="../../static/dt.png" mode="widthFix"></image>
					<text class="option-text">深度思考 (R1)</text>
				</view>
				<view class="option">
					<image class="option-icon" src="../../static/web.png" mode="widthFix"></image>
					<text class="option-text">联网搜索</text>
				</view>
				<view class="file">
					<image class="add-icon" src="../../static/add.png" mode="widthFix"></image>
				</view>
				<view class="send" @tap='sendMsg'>
					<image class="send-icon" src="../../static/send.png" mode="widthFix"></image>
				</view>
			</view>
		</view>

		<!-- 弹出窗 -->
		<view>
			<!-- 普通弹窗 -->
			<uni-popup class="history" ref="popup" background-color="#fff" @change="change">
				<view class="popup-content" :class="{ 'popup-height': type === 'left' || type === 'right' }">
					<!-- 对话列表：开始 -->
					<view class="chat-container">
						<!-- 今天的对话 -->
						<view class="chat-item" v-for="h in historylist" @tap="getTopic(h.id)"
							@longpress="delTopic(h.id)">
							<view class="chat-bubble" :class="current_topic_id == h.id ? 'selected':''">
								{{h.title}}
							</view>
						</view>
					</view>
					<!-- 对话列表：结束 -->
				</view>
			</uni-popup>
		</view>
	</view>
</template>


<!-- 行为层 -->
<script>
	// 导入全局变量 @是指根路径
	import config from '@/common/config.js'
	
	async function fetchSSE(url, options, onMessage) {
		const response = await fetch(url, {
			method: "POST",
			headers: {
				"Content-Type": "application/x-www-form-urlencoded"
			},
			body: new URLSearchParams(options.body)
		});

		const reader = response.body.getReader();
		const decoder = new TextDecoder("utf-8");

		while (true) {
			const {value, done} = await reader.read();
			if (done) break;
			const chunk = decoder.decode(value, {
				stream: true
			});
			// 服务端 SSE 一般格式: "data: xxx\n\n"
			chunk.split("\n\n").forEach(line => {
				if (line.startsWith("data:")) {
					onMessage(line.slice(5).trim());
				}
			});
		}
	}
	
	export default {
		data() {
			return {
				dt_bgc: '#f7f7f7',
				type: 'center',
				msg: '',
				chatlists: [
					// {role:'user', content:'1+1=多少，直接给我结果'},
					// {role:'assistant', content:'1 + 1 = 2。接下来，我需要'}
				],
				streamcontent: '',
				scroll: true,
				topic_id: 0, //当前对话的主题id
				historylist: [], //历史对话记录
				current_topic_id: 0, //当前选中的topic_id
			}
		},
		onPageScroll(e) {
			this.scroll = false
		},
		methods: {
			delTopic(topic_id) {
				console.log(topic_id)
				// 删除是危险操作,,必须有提示
				let _this = this
				uni.showModal({
					title: '确认',
					content: '是否确定删除？',
					success: function(res) {
						if (res.confirm) {
							console.log('用户点击确定');
							// 发起一个请求到服务器端进行数据删除
							uni.request({
								url: config.baseUrl + '/ai/deltopic/', //对话列表路由
								data: {
									topic_id: topic_id
								},
								success: (res) => {
									console.log(res.data);
									if (res.data.code == '200') {
										// 删除对应的主题
										for (let i = 0; i < _this.historylist.length; i++) {
											if (_this.historylist[i].id == topic_id) {
												// 从historylist移除删除的主题
												_this.historylist.splice(i, 1)
												break
											}
										}
									}
								}
							});

						} else if (res.cancel) {
							console.log('用户点击取消');
						}
					}
				})

			},
			getTopic(topic_id) {
				this.current_topic_id = topic_id
				// 弹出窗关闭
				this.$refs.popup.close()
				// 向服务器发起请求:获取该主题的历史对话信息
				uni.request({
					url: config.baseUrl + '/ai/chathistory/', //对话列表路由
					data: {
						topic_id: topic_id
					},
					success: (res) => {
						console.log(res.data);
						this.chatlists = res.data.data
						// 在历史的主题之上接着聊
						this.topic_id = topic_id
					}
				});

			},
			deepThing() {
				this.dt_bgc = this.dt_bgc == '#f7f7f7' ? '#cccccc' : '#f7f7f7'
			},
			newChat() {
				// 所有的数据全部初始化
				this.msg = ''
				this.chatlists = [],
					this.topic_id = 0
			},
			change(e) {
				console.log('当前模式：' + e.type + ',状态：' + e.show);
				// 我是不是说每次都要去请求服务器呢?
				if (this.historylist.length > 0) {
					return false
				}
				// 此时,我们需要到服务器获取历史对话记录
				uni.request({
					url: config.baseUrl + '/ai/chatlist/', //对话列表路由
					success: (res) => {
						console.log(res.data);
						this.historylist = res.data.data

					}
				});
			},
			toggle(type) {
				this.type = type
				// open 方法传入参数 等同在 uni-popup 组件上绑定 type属性
				this.$refs.popup.open(type)
			},

			sendMsg() {
				// 当你提出新的问题的时候,默认是自动滚动的
				this.scroll = true

				// 声明一个变量缓存输入框的数据,方便下面使用：let声明变量
				let msg = this.msg.trim()
				// 必须输入对话内容
				if (msg == '') {
					uni.showToast({
						title: '请输入内容',
						icon: 'error',
						duration: 1000
					})
					// 不让代码再往下执行
					return false
				}

				console.log(msg)
				// 追加用户提问到对话列表
				this.chatlists.push({
					role: 'user',
					content: msg
				})
				// 清空对话框
				this.msg = ''
				// 使用：
				/*
					和SourceEvent对比：
					1，请求的地址没有改变；
					2，提交的数据没有改变；
					3，业务处理没有改变；
					4，唯一的变化就是请求方法：从GET请求，变成了POST请求，支持各种特殊字符和各种长度，2G
				*/
				fetchSSE(config.baseUrl + '/ai/aichat/', {
					body: {
						question: msg,
						topic_id: this.topic_id
					}
				}, (msg) => {
					console.log("收到:", msg);
					if (msg === "[DONE]") {
						console.log("流式结束")
						// 把streamcontent追加到list列表
						this.chatlists.push({
							role: 'assistant',
							content: this.streamcontent
						})
						// 并清空streamcontent
						this.streamcontent = ''
						return
					}
					// 获取对话的主题ID
					if (msg.includes("<topic_id__IGCV>")) {
						this.topic_id = msg.match(/<topic_id__IGCV>(\d+)<\/topic_id__IGCV>/)[1];
						console.log('当前聊天的主题ID：', this.topic_id)
						return false
					}

					// 临时显示数据处理
					this.streamcontent = this.streamcontent + msg.replace(/\\n/g, "\n")
					// 滚动条自动滚动最下面:方便用户实时看到最新的消息
					if (this.scroll) {
						uni.pageScrollTo({
							scrollTop: 99999999999, // 滚动到距离页面顶部 200px 位置
							duration: 300 // 滚动动画时长（ms）
						})
					}
				});
				return false
				
				//发起请求
				// const evtSource = new EventSource("http://192.168.3.9:8003/ai/aichat/?question=" + encodeURIComponent(
				// 	msg) + '&topic_id=' +
				// 	this.topic_id);
				// evtSource.onmessage = (event) => {
				// 	if (event.data === "[DONE]") {
				// 		console.log("流式结束")
				// 		evtSource.close()
				// 		// 把streamcontent追加到list列表
				// 		this.chatlists.push({
				// 			role: 'assistant',
				// 			content: this.streamcontent
				// 		})
				// 		// 并清空streamcontent
				// 		this.streamcontent = ''
				// 		return
				// 	}
				// 	// 获取对话的主题ID
				// 	if (event.data.includes("<topic_id__IGCV>")) {
				// 		this.topic_id = event.data.match(/<topic_id__IGCV>(\d+)<\/topic_id__IGCV>/)[1];
				// 		console.log('当前聊天的主题ID：', this.topic_id)
				// 		return false
				// 	}

				// 	console.log("收到:", JSON.stringify(event.data))
				// 	// 临时显示数据处理
				// 	this.streamcontent = this.streamcontent + event.data.replace(/\\n/g, "\n")
				// 	// 滚动条自动滚动最下面:方便用户实时看到最新的消息
				// 	if (this.scroll) {
				// 		uni.pageScrollTo({
				// 			scrollTop: 99999999999, // 滚动到距离页面顶部 200px 位置
				// 			duration: 300 // 滚动动画时长（ms）
				// 		})
				// 	}
				// }

			}
		}
	}
</script>



<style>
	.chat-container {
		width: 560rpx;
		box-sizing: border-box;
	}

	.chat-time {
		font-size: 28rpx;
		color: #999;
		display: block;
	}

	/* 普通气泡 */
	.chat-bubble {
		/* 保证在弹层里适配 */
		padding: 3% 2%;
		background-color: #fff;
		border-radius: 8rpx;
		font-size: 32rpx;
		color: #333;
		white-space: nowrap;
		/* 不换行 */
		overflow: hidden;
		/* 超出隐藏 */
		text-overflow: ellipsis;
		/* 超出显示省略号 */
	}

	/* 选中气泡 */
	.chat-bubble.selected {
		background-color: #e6f0ff;
		color: #2a62ff;
	}
</style>


<style lang="scss">
	@mixin flex {
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		flex-direction: row;
	}

	@mixin height {
		/* #ifndef APP-NVUE */
		height: 100%;
		/* #endif */
		/* #ifdef APP-NVUE */
		flex: 1;
		/* #endif */
	}

	.box {
		@include flex;
	}

	.button {
		@include flex;
		align-items: center;
		justify-content: center;
		flex: 1;
		height: 35px;
		margin: 0 5px;
		border-radius: 5px;
	}

	.example-body {
		background-color: #fff;
		padding: 10px 0;
	}

	.button-text {
		color: #fff;
		font-size: 12px;
	}

	.popup-content {
		@include flex;
		align-items: flex-start;
		justify-content: center;
		padding: 10rpx;
		height: 100rpx;
		background-color: #fff;
	}

	.popup-height {
		@include height;
		width: 600rpx;
	}

	.text {
		font-size: 12px;
		color: #333;
	}

	.popup-success {
		color: #fff;
		background-color: #e1f3d8;
	}

	.popup-warn {
		color: #fff;
		background-color: #faecd8;
	}

	.popup-error {
		color: #fff;
		background-color: #fde2e2;
	}

	.popup-info {
		color: #fff;
		background-color: #f2f6fc;
	}

	.success-text {
		color: #09bb07;
	}

	.warn-text {
		color: #e6a23c;
	}

	.error-text {
		color: #f56c6c;
	}

	.info-text {
		color: #909399;
	}

	.dialog,
	.share {
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		flex-direction: column;
	}

	.dialog-box {
		padding: 10px;
	}

	.dialog .button,
	.share .button {
		/* #ifndef APP-NVUE */
		width: 100%;
		/* #endif */
		margin: 0;
		margin-top: 10px;
		padding: 3px 0;
		flex: 1;
	}

	.dialog-text {
		font-size: 14px;
		color: #333;
	}
</style>



<style scoped>
	.nav-bar-empty {
		height: 120rpx;
	}

	.message-container {
		display: flex;
		flex-direction: column;
		padding: 16rpx;
	}

	.message-item {
		display: flex;
		margin-bottom: 24rpx;
	}

	.user-message {
		justify-content: flex-start;
	}

	.reply-message {
		justify-content: flex-end;
	}

	.avatar {
		width: 80rpx;
		height: 80rpx;
		border-radius: 50%;
		margin: 0 16rpx;
	}

	.message-content {
		background-color: #e5f2ff;
		/* 用户消息浅蓝色背景，可按需调整 */
		padding: 16rpx;
		border-radius: 20rpx;
		max-width: 560rpx;
		/* 限制消息内容宽度，可按需调整 */
	}

	.wbg {
		background-color: #fff;
	}

	.message-text {
		font-size: 32rpx;
		color: #333;
	}
</style>


<style>
	.tmp-bottom {
		width: 750rpx;
		height: 180rpx;
	}

	.container {
		display: flex;
		flex-direction: column;
		height: 100vh;
		background-color: #ffffff;
	}

	/* 顶部导航栏 */
	.nav-bar {
		position: fixed;
		left: 0;
		right: 0;
		display: flex;
		flex-direction: row;
		justify-content: space-between;
		align-items: center;
		height: 100rpx;
		padding: 0 30rpx;
		border-bottom: 1rpx solid #f0f0f0;
		background-color: #fff;
		z-index: 10;
	}

	.nav-icon {
		width: 40rpx;
		height: 40rpx;
	}

	.nav-title {
		font-size: 32rpx;
		font-weight: bold;
		color: #000000;
	}

	/* 中间主区域 */
	.main-content {
		flex: 1;
		justify-content: center;
		align-items: center;
		text-align: center;
		display: flex;
		flex-direction: column;
	}

	.logo {
		width: 120rpx;
		height: 120rpx;
		margin-bottom: 30rpx;
	}

	.welcome {
		font-size: 36rpx;
		font-weight: bold;
		margin-bottom: 20rpx;
	}

	.desc {
		font-size: 28rpx;
		color: #999999;
		line-height: 48rpx;
		padding: 0 80rpx;
	}

	/* 底部输入区域 */
	.input-area {
		position: fixed;
		bottom: 0;
		left: 0;
		right: 0;
		z-index: 10;

		width: 690rpx;
		padding: 20rpx 30rpx;
		border-top: 1rpx solid #f0f0f0;
		background-color: #ffffff;
		display: flex;
		flex-direction: column;
	}

	/* 输入框样式 */
	.msg-input {
		width: 610rpx;
		line-height: 80rpx;
		border-radius: 40rpx;
		background-color: #f7f7f7;
		padding: 0 30rpx;
		font-size: 28rpx;
		margin-bottom: 20rpx;
	}

	.input-placeholder {
		color: #999999;
		font-size: 28rpx;
	}

	.input-options {
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}

	.option {
		display: flex;
		flex-direction: row;
		align-items: center;
		background-color: #f7f7f7;
		border-radius: 30rpx;
		padding: 10rpx 20rpx;
		margin-right: 20rpx;
	}

	.option-icon {
		width: 36rpx;
		height: 36rpx;
		margin-right: 10rpx;
	}

	.option-text {
		font-size: 26rpx;
		color: #333333;
	}

	.send {
		width: 60rpx;
		height: 60rpx;
		background-color: aqua;
		border-radius: 50%;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.send-icon {
		width: 50rpx;
		height: 50rpx;

	}

	.add-icon {
		width: 45rpx;
		height: 45rpx;

	}
</style>